#include "handlers/http_handler.hpp"
#include "database/user_dao.hpp"
#include "utils/crypto.hpp"
#include "utils/token.hpp"
#include "common/response.hpp"
#include "models/user.hpp"
#include <workflow/HttpUtil.h>
#include <nlohmann/json.hpp> 
#include <iostream>


using json = nlohmann::json;

// --- 用户注册 ---
void HttpHandlers::handleSignup(WFHttpTask *task) {
    const void* body;
    size_t size;
    task->get_req()->get_parsed_body(&body, &size);

    try {
        json req_json = json::parse(static_cast<const char*>(body), static_cast<const char*>(body) + size);
        std::string username = req_json.at("username");
        std::string password = req_json.at("password");

        if (UserDao::userExists(username)) {
            task->get_resp()->append_output_body(Response::jsonError("Username already exists."));
            task->get_resp()->set_status_code("409"); // 409 Conflict
            return;
        }

        User user;
        user.username = username;
        user.salt = Crypto::generateSalt();
        user.password = Crypto::hashPassword(password, user.salt);

        if (UserDao::createUser(user)) {
            task->get_resp()->append_output_body(Response::jsonSuccess({{"message", "User registered successfully."}}));
            task->get_resp()->set_status_code("201"); // 201 Created
        } else {
            task->get_resp()->append_output_body(Response::jsonError("Failed to create user."));
            task->get_resp()->set_status_code("500");
        }
    } catch (const json::exception& e) {
        task->get_resp()->append_output_body(Response::jsonError("Invalid JSON format or missing fields."));
        task->get_resp()->set_status_code("400");
    }
}

// --- 用户登录 ---
void HttpHandlers::handleSignin(WFHttpTask *task) {
    const void* body;
    size_t size;
    task->get_req()->get_parsed_body(&body, &size);

    try {
        json req_json = json::parse(static_cast<const char*>(body), static_cast<const char*>(body) + size);
        std::string username = req_json.at("username");
        std::string password = req_json.at("password");

        auto user_opt = UserDao::getUserByUsername(username);
        if (!user_opt.has_value()) {
            task->get_resp()->append_output_body(Response::jsonError("Invalid username or password."));
            task->get_resp()->set_status_code("401"); // 401 Unauthorized
            return;
        }

        if (Crypto::verifyPassword(password, user_opt->salt, user_opt->password)) {
            std::string token = Token::generate(username);
            json data;
            data["token"] = token;
            data["username"] = username;
            task->get_resp()->append_output_body(Response::jsonSuccess(data));
        } else {
            task->get_resp()->append_output_body(Response::jsonError("Invalid username or password."));
            task->get_resp()->set_status_code("401");
        }
    } catch (const json::exception& e) {
        task->get_resp()->append_output_body(Response::jsonError("Invalid JSON format or missing fields."));
        task->get_resp()->set_status_code("400");
    }
}

// --- 获取用户信息 ---
void HttpHandlers::handleGetUserInfo(WFHttpTask *task) {
    const auto* req = task->get_req();
    protocol::HttpHeaderCursor cursor(req);
    std::string auth_header;
    std::string token;

    if (cursor.find("Authorization", auth_header) && auth_header.rfind("Bearer ", 0) == 0) {
        token = auth_header.substr(7);
    }

    if (token.empty()) {
        task->get_resp()->set_status_code("401");
        task->get_resp()->append_output_body(Response::jsonError("Authorization header is missing or invalid."));
        return;
    }

    std::string username = Token::extractUsername(token);
    if (username.empty()) {
        task->get_resp()->set_status_code("401");
        task->get_resp()->append_output_body(Response::jsonError("Invalid or expired token."));
        return;
    }

    auto user_opt = UserDao::getUserByUsername(username);
    if (!user_opt.has_value()) {
        task->get_resp()->set_status_code("404");
        task->get_resp()->append_output_body(Response::jsonError("User not found."));
        return;
    }

    json user_info;
    user_info["username"] = user_opt->username;
    user_info["signup_at"] = user_opt->created_at;
    
    task->get_resp()->append_output_body(Response::jsonSuccess(user_info));
    task->get_resp()->set_status_code("200");
}

// --- 通用处理器 ---
void HttpHandlers::handleNotFound(WFHttpTask *task) {
    task->get_resp()->set_status_code("404");
    task->get_resp()->append_output_body(Response::jsonError("Not Found"));
}

void HttpHandlers::handleRoot(WFHttpTask *task) {
    task->get_resp()->set_status_code("302");
    task->get_resp()->add_header_pair("Location", "/static/view/login.html");
}
